home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
inn1.000
/
inn1.4sec-linux-src.tar
/
inn
/
frontends
/
sys2nf.c
< prev
Wrap
C/C++ Source or Header
|
1993-01-29
|
7KB
|
333 lines
/* $Revision: 1.3 $
**
** Read a C news "sys" file and split it up into a set of INN
** newsfeeds entries. Also works with B news.
**
** Once done, edit all files that have HELP or all in them.
** Review all files, anyway.
*/
#include "configdata.h"
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "nntp.h"
#include "libinn.h"
#include "clibrary.h"
#include "macros.h"
#define TEMPFILE ":tmp"
static char **Groups;
/*
** Fill in the Groups array with the names of all active newsgroups.
*/
static void
ReadActive(act)
char *act;
{
FILE *F;
int i;
char buff[BUFSIZ];
char *p;
/* Open file, count lines. */
if ((F = fopen(act, "r")) == NULL) {
perror(act);
exit(1);
}
for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
continue;
Groups = NEW(char*, i + 2);
/* Fill in each word. */
rewind(F);
for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++) {
if ((p = strchr(buff, ' ')) != NULL)
*p = '\0';
Groups[i] = COPY(buff);
}
Groups[i] = NULL;
(void)fclose(F);
}
/*
** Read in the sys file and turn it into an array of strings, one
** per continued line.
*/
char **
ReadSys(sys)
char *sys;
{
register char *p;
register char *to;
register char *site;
register int i;
char *data;
char **strings;
/* Read in the file, get rough count. */
if ((data = ReadInFile(sys, (struct stat *)NULL)) == NULL) {
perror(sys);
exit(1);
}
for (p = data, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
continue;
/* Scan the file, glue all multi-line entries. */
for (strings = NEW(char*, i + 1), i = 0, to = p = data; *p; ) {
for (site = to; *p; ) {
if (*p == '\n') {
p++;
*to = '\0';
break;
}
if (*p == '\\' && p[1] == '\n')
while (*++p && CTYPE(isspace, *p))
continue;
else
*to++ = *p++;
}
*to++ = '\0';
if (*site == '\0')
continue;
strings[i++] = COPY(site);
}
strings[i] = NULL;
DISPOSE(data);
return strings;
}
/*
** Is this the name of a top-level group? We want a simple name, "foo",
** and should find a "foo." in the group list.
*/
static BOOL
Toplevel(p)
char *p;
{
char **gp;
char *g;
int i;
if (strchr(p, '.') != NULL)
return FALSE;
for (i = strlen(p) - 1, gp = Groups; (g = *gp++) != NULL; )
if (EQn(p, g, i) && g[i + 1] == '.')
return TRUE;
return FALSE;
}
/*
** Do we have a name that's a prefix for more then one newsgroup?
** For "foo.bar", we must find more then one "foo.bar" or "foo.bar."
*/
static BOOL
GroupPrefix(p)
char *p;
{
char **gp;
char *g;
int count;
int i;
if (strchr(p, '.') == NULL)
return FALSE;
for (i = strlen(p), count = 0, gp = Groups; (g = *gp++) != NULL; )
if (EQ(p, g) || (EQn(p, g, i) && g[i] == '.'))
count++;
return count > 1;
}
/*
** Step through the old subscription list, try to update each one in
** turn.
*/
static void
DoSub(F, p)
register FILE *F;
char *p;
{
register char *s;
register int len;
register BOOL SawBang;
register BOOL SawAll;
if ((s = strtok(p, ",")) == NULL)
return;
(void)fprintf(F, "!*");
len = 8 + 1 + 2;
do {
/* These are distributions, not newsgroups. */
if (EQ(s, "world") || EQ(s, "na") || EQ(s, "usa") || EQ(s, "inet")
|| EQ(s, "mod") || EQ(s, "net")
|| EQ(s, "local")
)
continue;
#if defined(DO_MERGE_TO_GROUPS)
if (EQ(s, "!to") || EQn(s, "to.", 3))
continue;
#endif /* defined(DO_MERGE_TO_GROUPS) */
(void)putc(',', F);
len++;
if (len + strlen(s) + 3 > 72) {
(void)fprintf(F,"\\\n\t ");
len = 12;
}
SawBang = *s == '!';
if (SawBang) {
(void)putc('!', F);
len++;
s++;
}
SawAll = EQ(s, "all");
if (SawAll)
s = SawBang ? "*" : "*,!control";
len += strlen(s);
(void)fprintf(F, "%s", s);
if (SawAll)
;
else if (
EQ(s, "comp") || EQ(s, "misc") || EQ(s, "news") || EQ(s, "rec")
|| EQ(s, "sci") || EQ(s, "soc") || EQ(s, "talk")
|| EQ(s, "alt") || EQ(s, "bionet") || EQ(s, "bit") || EQ(s, "biz")
|| EQ(s, "clari") || EQ(s, "ddn") || EQ(s, "gnu") || EQ(s, "ieee")
|| EQ(s, "k12") || EQ(s, "pubnet") || EQ(s, "trial") || EQ(s, "u3b")
|| EQ(s, "vmsnet")
|| EQ(s, "ba") || EQ(s, "ca") || EQ(s, "dc") || EQ(s, "ne")
|| EQ(s, "ny") || EQ(s, "tx")
|| EQ(s, "info") || EQ(s, "mail") || EQ(s, "opinions")
|| EQ(s, "uunet")
|| Toplevel(s)) {
(void)fprintf(F, ".*");
len += 2;
}
else if (GroupPrefix(s)) {
(void)putc('*', F);
len++;
}
} while ((s = strtok((char *)NULL, ",")) != NULL);
}
int
main(ac, av)
int ac;
char *av[];
{
FILE *F;
FILE *out;
char **sites;
char *f2;
char *f3;
char *f4;
char *p;
char *q;
char *site;
char buff[256];
char *act;
char *dir;
char *sys;
int i;
/* Set defaults. */
act = "/usr/local/lib/newslib/active";
sys = "sys";
dir = "feeds";
while ((i = getopt(ac, av, "a:s:d:")) != EOF)
switch (i) {
default:
exit(1);
/* NOTREACHED */
case 'a': act = optarg; break;
case 'd': dir = optarg; break;
case 's': sys = optarg; break;
}
sites = ReadSys(sys);
ReadActive(act);
if (mkdir(dir, 0777) < 0 && errno != EEXIST)
perror(dir), exit(1);
if (chdir(dir) < 0)
perror("chdir"), exit(1);
for ( ; ; ) {
/* Get next non-comment ilne. */
if ((p = *sites++) == NULL)
break;
for (F = fopen(TEMPFILE, "w"); p && *p == '#'; p = *sites++)
(void)fprintf(F, "%s\n", p);
if (p == NULL) {
(void)fclose(F);
break;
}
site = COPY(p);
if ((f2 = strchr(site, ':')) == NULL)
f2 = "HELP";
else
*f2++ = '\0';
if ((f3 = strchr(f2, ':')) == NULL)
f3 = "HELP";
else
*f3++ = '\0';
if ((f4 = strchr(f3, ':')) == NULL)
f4 = "HELP";
else
*f4++ = '\0';
/* Write the fields. */
(void)fprintf(F, "%s\\\n", site);
(void)fprintf(F, "\t:");
DoSub(F, f2);
(void)fprintf(F, "\\\n");
if (EQ(f3, "n"))
(void)fprintf(F, "\t:Tf,Wnm\\\n", f3);
else
(void)fprintf(F, "\t:HELP%s\\\n", f3);
(void)fprintf(F, "\t:%s\n", f4);
if (ferror(F) || fclose(F) == EOF)
perror(TEMPFILE), exit(1);
DISPOSE(site);
/* Find the sitename. */
for (q = p; *q && *q != '/' && *q != ':'; q++)
continue;
*q = '\0';
/* Append temp file to site file. */
if ((F = fopen(TEMPFILE, "r")) == NULL)
perror(TEMPFILE), exit(1);
if ((out = xfopena(p)) == NULL)
perror(p), exit(1);
while ((i = fread(buff, 1, sizeof buff, F)) > 0)
if (fwrite(buff, 1, i, out) != i)
perror(p), exit(1);
(void)fclose(F);
if (fclose(out) == EOF)
perror(p), exit(1);
if (unlink(TEMPFILE) < 0)
perror("can't unlink temp file");
}
exit(0);
/* NOTREACHED */
}